package com.wingy.psyduckplayer.Activity;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.wingy.psyduckplayer.Data.Music;
import com.wingy.psyduckplayer.Data.MusicList;
import com.wingy.psyduckplayer.R;

import java.util.ArrayList;
import java.util.Random;

public class MusicService extends Service {

    //控制命令，标识操作
    public static final int COMMAND_UNKOWN = -1;
    public static final int COMMAND_PLAY = 0;
    public static final int COMMAND_PAUSE = 1;
    public static final int COMMAND_STOP = 2;
    public static final int COMMAND_RESUME = 3;
    public static final int COMMAND_PREVIOUS = 4;
    public static final int COMMAND_NEXT = 5;
    public static final int COMMAND_CHECK_IS_PLAYING = 6;
    public static final int COMMAND_SEEK_TO = 7;
    public static final int COMMAND_RANDOM = 8;
    public static final int COMMAND_RANDOM_NEXT = 9;
    public static final int COMMAND_RANDOM_PREVIOUS = 10;
    //播放器状态
    public static final int STATUS_PLAYING = 0;
    public static final int STATUS_PAUSED = 1;
    public static final int STATUS_STOPPED = 2;
    public static final int STATUS_COMPLETED = 3;

    //广播标识
    public static final String BROADCAST_MUSICSERVICE_CONTROL = "MusicService.ACTION_CONTROL";
    public static final String BROADCAST_MUSICSERVICE_UPDATE_STATUS = "MusicService.ACTION_UPDATE";

    //歌曲序号，从0开始
    private int number = 0;
    private int randomnum = 0;
    private ArrayList<Integer> randomList = new ArrayList<Integer>();
    private ArrayList<Integer> playedList = new ArrayList<Integer>();
    private int status;
    //媒体播放类
    private MediaPlayer player = new MediaPlayer();

    //广播接收器
    private CommandReceiver receiver;

    private boolean phone = false;

    private NotificationManager manager;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        bindCommandReceiver();
        status = MusicService.STATUS_STOPPED;
        randomList.clear();
        playedList.clear();
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new MyPhoneListener(), PhoneStateListener.LISTEN_CALL_STATE);
    }

    private final class MyPhoneListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    if(status == MusicService.STATUS_PLAYING) {
                        pause();
                        phone = true;
                    }
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    if(phone) {
                        resume();
                        phone = false;
                    }
                    break;
            }
        }
    }

    @Override
    public void onDestroy() {
        sendBroadcastOnStatusChanged(MusicService.STATUS_STOPPED);
        manager.cancel(0x3131);
        //释放播放器资源
        if(player != null)
            player.release();
        if (status == MusicService.STATUS_STOPPED) {
            stopService(new Intent(this, MusicService.class));
        }
        super.onDestroy();
    }

    Boolean getFromList(int i) {
        for(Integer temp : playedList){
            if(i == temp) return true;
        }
        return false;
    }

    class CommandReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String ctrl_code = intent.getAction();
            if (BROADCAST_MUSICSERVICE_CONTROL.equals(ctrl_code)) {
                int command = intent.getIntExtra("command", COMMAND_UNKOWN);
                switch (command) {
                    case COMMAND_RANDOM_NEXT:
                        if(randomList.size() == 0 || randomnum == randomList.size()-1) {
                            Random rand = new Random();
                            int i;
                            if(playedList.size()==MusicList.getMusicList().size())  playedList.clear();
                            do {
                                i = rand.nextInt(MusicList.getMusicList().size());
                            } while (getFromList(i));
                            randomList.add(i);
                            playedList.add(i);
                            randomnum = randomList.size() - 1;
                            number = randomList.get(randomnum);
                            play(number);
                        } else {
                            ++randomnum;
                            number = randomList.get(randomnum);
                            play(number);
                        }
                        break;
                    case COMMAND_RANDOM_PREVIOUS:
                        if(randomnum == 0) {
                            Random rand = new Random();
                            int i;
                            if(playedList.size()==MusicList.getMusicList().size())  playedList.clear();
                            do {
                                i = rand.nextInt(MusicList.getMusicList().size());
                            } while (getFromList(i));
                            randomList.add(0, i);
                            playedList.add(i);
                            randomnum = 0;
                            number = randomList.get(randomnum);
                            play(number);
                        } else {
                            --randomnum;
                            number = randomList.get(randomnum);
                            play(number);
                        }
                        break;
                    case COMMAND_RANDOM:
                        if(randomList.size()==0) {
                            Random rand = new Random();
                            int i;
                            if (playedList.size() == MusicList.getMusicList().size())
                                playedList.clear();
                            do {
                                i = rand.nextInt(MusicList.getMusicList().size());
                            } while (getFromList(i));
                            randomList.add(i);
                            playedList.add(i);
                            number = randomList.get(randomnum);
                            randomnum = randomList.size() - 1;
                            play(number);
                        } else {
                            number = randomList.get(randomnum);
                            play(number);
                        }
                        break;
                    case COMMAND_SEEK_TO:
                        seekTo(intent.getIntExtra("time", 0));
                        break;
                    case COMMAND_PLAY:
                        number = intent.getIntExtra("number", 0);
                        play(number);
                        break;
                    case COMMAND_PREVIOUS:
                        moveNumberToPrevious();
                        break;
                    case COMMAND_NEXT:
                        moveNumberToNext();
                        break;
                    case COMMAND_PAUSE:
                        pause();
                        break;
                    case COMMAND_STOP:
                        stop();
                        break;
                    case COMMAND_RESUME:
                        resume();
                        break;
                    case COMMAND_CHECK_IS_PLAYING:
                        if (player != null && player.isPlaying()) {
                            sendBroadcastOnStatusChanged(MusicService.STATUS_PLAYING);
                        }
                        break;
                    case COMMAND_UNKOWN:
                    default:
                        break;
                }
            } else if("RESUME".equals(ctrl_code)) {
                resume();
            } else if("PAUSE".equals(ctrl_code)) {
                pause();
            } else if("PREVIOUS".equals(ctrl_code)) {
                moveNumberToPrevious();
            } else if("NEXT".equals(ctrl_code)) {
                moveNumberToNext();
            } else if("CLOSE".equals(ctrl_code)) {
                manager.cancel(0x3131);
                System.exit(0);
            }
        }
    }

    /**绑定广播接收器*/
    private void bindCommandReceiver() {
        receiver = new CommandReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(BROADCAST_MUSICSERVICE_CONTROL);
        filter.addAction("RESUME");
        filter.addAction("PAUSE");
        filter.addAction("NEXT");
        filter.addAction("PREVIOUS");
        filter.addAction("CLOSE");
        filter.addAction("SLEEPTIME");
        registerReceiver(receiver, filter);
    }

    /**发送广播*/
    private void sendBroadcastOnStatusChanged(int status) {
        Intent intent = new Intent(BROADCAST_MUSICSERVICE_UPDATE_STATUS);
        intent.putExtra("status", status);
        if(status != STATUS_STOPPED) {
            intent.putExtra("time", player.getCurrentPosition());
            intent.putExtra("duration", player.getDuration());
            intent.putExtra("number", number);
            intent.putExtra("musicName",MusicList.getMusicList().get(number).getmusicName());
            intent.putExtra("musicArtist",MusicList.getMusicList().get(number).getmusicArtist());

        }sendBroadcast(intent);
    }

    //播放结束监听器
    MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            if (player.isLooping()) {
                replay();
            } else {
                sendBroadcastOnStatusChanged(MusicService.STATUS_COMPLETED);
            }
        }
    };

    /** 读取音乐文件 */
    private void load(int number){
        try{
            player.reset();
            player.setDataSource(MusicList.getMusicList().get(number).getmusicPath());
            player.prepare();
            player.setLooping(false);
        }catch (Exception e){
            e.printStackTrace();
        }
        //注册监听器
        player.setOnCompletionListener(completionListener);
    }

    /** 播放音乐 */
    private void play(int number) {
        // 停止当前播放
        if (player != null && player.isPlaying()) {
            player.stop();
        }

        load(number);

        player.start();
        status = MusicService.STATUS_PLAYING;
        sendBroadcastOnStatusChanged(MusicService.STATUS_PLAYING);
        updateNotification();
    }
    /** 暂停音乐 */
    private void pause() {
        if (player.isPlaying()) {
            player.pause();
            status = MusicService.STATUS_PAUSED;
            sendBroadcastOnStatusChanged(MusicService.STATUS_PAUSED);
            updateNotification();
        }
    }
    /** 停止播放 */
    private void stop() {
        if (status != MusicService.STATUS_STOPPED) {
            player.stop();
            status = MusicService.STATUS_STOPPED;
            sendBroadcastOnStatusChanged(MusicService.STATUS_STOPPED);
            updateNotification();
        }

    }
    /** 恢复播放（暂停之后） */
    private void resume() {
        player.start();
        status = MusicService.STATUS_PLAYING;
        sendBroadcastOnStatusChanged(MusicService.STATUS_PLAYING);
        updateNotification();
    }
    /** 重新播放（播放完成之后） */
    private void replay() {
        player.start();
        status = MusicService.STATUS_PLAYING;
        sendBroadcastOnStatusChanged(MusicService.STATUS_PLAYING);
        updateNotification();
    }

    /** 选择下一曲 */
    private void moveNumberToNext() {
        // 判断是否到达了列表底端
        if(number == MusicList.getMusicList().size() - 1) {
            Toast.makeText(MusicService.this, MusicService.this.getString(R.string.tip_reach_bottom),Toast.LENGTH_SHORT).show();
            number = 0;
            play(number);
        }else {
            ++number;
            play(number);
        }
    }

    /** 选择上一曲 */
    private void moveNumberToPrevious() {
        // 判断是否到达了列表顶端
        if (number == 0) {
            Toast.makeText(MusicService.this,MusicService.this.getString(R.string.tip_reach_top),Toast.LENGTH_SHORT).show();
            number = MusicList.getMusicList().size() - 1;
            play(number);
        } else {
            --number;
            play(number);
        }

    }

    /**跳转到播放位置*/
    private  void seekTo(int time) {
        player.seekTo(time);
        status = MusicService.STATUS_PLAYING;
        sendBroadcastOnStatusChanged(MusicService.STATUS_PLAYING);
        updateNotification();
    }

    private void updateNotification() {
        manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = manager.getNotificationChannel("PsyduckPlayer");
            if (notificationChannel == null) {
                int importance = NotificationManager.IMPORTANCE_DEFAULT; //Set the importance level
                notificationChannel = new NotificationChannel("PsyduckPlayer", "PsyduckPlayer", importance);
                manager.createNotificationChannel(notificationChannel);
            }
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        RemoteViews view = new RemoteViews(getPackageName(), R.layout.statusbar);
        view.setImageViewResource(R.id.imageView, R.mipmap.ic_launcher);
        view.setTextViewText(R.id.notification_musicname, MusicList.getMusicList().get(number).getmusicName());
        view.setTextViewText(R.id.notification_artist, MusicList.getMusicList().get(number).getmusicArtist());

        if(status == MusicService.STATUS_PLAYING) {
            view.setViewVisibility(R.id.play, View.GONE);
            view.setViewVisibility(R.id.pause, View.VISIBLE);
        } else {
            view.setViewVisibility(R.id.play, View.VISIBLE);
            view.setViewVisibility(R.id.pause, View.GONE);
        }

        view.setOnClickPendingIntent(R.id.previous, pre_PendingIntent());
        view.setOnClickPendingIntent(R.id.next, next_PendingIntent());
        view.setOnClickPendingIntent(R.id.play, play_PendingIntent());
        view.setOnClickPendingIntent(R.id.pause, pause_PendingIntent());
        view.setOnClickPendingIntent(R.id.cancel, close_PendingIntent());

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        builder.setContent(view)
                .setContentIntent(pendingIntent)
                .setPriority(Notification.PRIORITY_MAX)
                .setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setChannelId("PsyduckPlayer");

        Notification notification = builder.build();
        notification.flags = Notification.FLAG_ONGOING_EVENT;
        manager.notify(0x3131, notification);
    }

    private PendingIntent close_PendingIntent() {
        Intent intent = new Intent("CLOSE");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent ,0);
        return pendingIntent;
    }

    private PendingIntent next_PendingIntent() {
        Intent intent = new Intent("NEXT");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent ,0);
        return pendingIntent;
    }

    private PendingIntent pre_PendingIntent() {
        Intent intent = new Intent("PREVIOUS");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent ,0);
        return pendingIntent;
    }

    private PendingIntent play_PendingIntent() {
        Intent intent = new Intent("RESUME");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent ,0);
        return pendingIntent;
    }

    private PendingIntent pause_PendingIntent() {
        Intent intent = new Intent("PAUSE");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent ,0);
        return pendingIntent;
    }
}
